﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Text.RegularExpressions;

namespace Ex1.StudentsFromGroup2
{
    public class Student
    {
        public string FirstName { get; set; }
        public string LastName { get; set; }
        public int FN { get; set; }
        public string Tel { get; set; }
        public string Email { get; set; }
        public List<int> Marks { get; set; }
        public int GroupNumber { get; set; }

        public Student(string fName, string lName, int fn, string tel,
            string email, List<int> marks, int group)
        {
            this.FirstName = fName;
            this.LastName = lName;
            this.FN = fn;
            this.Tel = tel;
            this.Email = email.ToLower();
            this.Marks = marks;
            this.GroupNumber = group;
        }

        public override string ToString()
        {
            return string.Format("FirstName: {0}\nLastName: {1}\nFN: {2}\nTEL: {3}\nEmail: {4}\nGroup: {5}\n",
                this.FirstName, this.LastName, this.FN, this.Tel, this.Email, this.GroupNumber) +
                string.Format("Marks: {0}", GetMarks());
        }

        public string GetMarks()
        {
            StringBuilder marks = new StringBuilder();
            foreach (var item in this.Marks)
            {
                marks.Append(item + " ");
            }
            return marks.ToString();
        }
    }

    public class Group
    {
        public int GroupNumber { get; set; }
        public string DepartmentName { get; set; }

        public Group(int gNumber, string dName)
        {
            this.GroupNumber = gNumber;
            this.DepartmentName = dName;
        }
    }

    public class LINQStudents
    {
        public static void PrintResult(IEnumerable<Student> collection)
        {
            Console.WriteLine(new string('-',30));
            foreach (var student in collection)
            {
                Console.WriteLine(student + "\n");
            }
            Console.WriteLine(new string('-', 30));
        }

        static void Main(string[] args)
        {
            List<Student> students = new List<Student>();
            students.Add(new Student("Pesho", "Peshov", 65012,"02-12345678",
                "pesho@gmail.com", new List<int> { 2, 6, 6 }, 2));

            students.Add(new Student("Pesho2", "Peshov", 65012,"7862134567",
                "pesho2@pesho.com", new List<int> { 5, 3, 6 }, 1));
            students.Add(new Student("Pesho3", "Peshov", 65012,"5412365412",
                "pesho3@abv.bg", new List<int> { 2, 3, 6 }, 2));
            students.Add(new Student("Pesho4", "Peshov", 650106,"02123645212",
                "pesho4@pesho.com", new List<int> { 2, 6, 4 }, 4));
            students.Add(new Student("Pesho5", "Peshov", 650106,"02-12345678",
                "pesho5@abv.bg", new List<int> { 2, 3, 4 }, 3));

            List<Group> groups = new List<Group>();
            groups.Add(new Group(1,"Mathematics"));
            groups.Add(new Group(2,"Informathics"));
            groups.Add(new Group(3,"Chemistry"));
            groups.Add(new Group(4,"Phisics"));

            //Ex1 - Students from 2 group (LINQ)
            //var studentsFromGroup2LINQ =
            //    from student in students
            //    where student.GroupNumber == 2
            //    orderby student.FirstName
            //    select student;
            //Console.WriteLine("Students from 2 group (LINQ)\n");
            //PrintResult(studentsFromGroup2LINQ);

            //Ex2 - Students from 2 group (Extensions)
            //var studentsGroup2Extensions = students.Where(st => st.GroupNumber == 2).OrderBy(st => st.FirstName);
            //Console.WriteLine("\nStudents from 2 group (Extensions): \n");
            //PrintResult(studentsGroup2Extensions);

            //Ex3 - Students with ABV emails
            //var studentsWithABVEmails =
            //    from student in students
            //    where student.Email.Contains("abv.bg")
            //    select student;
            //Console.WriteLine("\nStudents with ABV emails: \n");
            //PrintResult(studentsWithABVEmails);

            //Ex4 - Students with phones in Sofia
            //string expression = "^02-[0-9]{8}$";
            //var studentsWithPhonesInSofia =
            //    from student in students
            //    where Regex.IsMatch(student.Tel, expression)
            //    select student;
            //Console.WriteLine("\nStudents with phones in Sofia: \n");
            //PrintResult(studentsWithPhonesInSofia);

            //Ex5 - Students with at least one 6
            //var excellentStudents =
            //    from student in students
            //    where student.Marks.Contains(6)
            //    select new
            //    {
            //        FullName = string.Format("{0} {1}", student.FirstName, student.LastName),
            //        Marks = student.GetMarks()
            //    };

            //Console.WriteLine("\nStudents with at least one 6: \n");
            //Console.Write(new string('-', 30));
            //Console.WriteLine();
            //foreach (var student in excellentStudents)
            //{
            //    Console.WriteLine("FullName: {0}",student.FullName);
            //    Console.WriteLine("Marks: {0}",student.Marks);
            //}
            //Console.WriteLine(new string('-', 30));

            //Ex6 - Students with two 6
            //var betterGradedStudents = students.Where(st => st.Marks.FindAll(mark => mark.Equals(6)).Count == 2);
            //Console.WriteLine("\nStudents with two 6: \n");
            //PrintResult(betterGradedStudents);

            //Ex7 - Students enrolled in 2006
            //var marksOfStudents06 =
            //    from student in students
            //    where student.FN.ToString().EndsWith("06")
            //    select student;
            //Console.WriteLine("\nStudents enrolled in 2006: \n");
            //PrintResult(marksOfStudents06);

            //Ex8 - Students from Department Mathematics
            //var studentsFromMaths =
            //    from student in students
            //    join g in groups on student.GroupNumber equals g.GroupNumber
            //    where g.DepartmentName == "Mathematics"
            //    select student;
            //Console.WriteLine("\nStudents from Department Mathematics: \n");
            //PrintResult(studentsFromMaths);

            //Ex9
            //string[] someStrings = new string[] {"a","aa","bbb","äsuytregfd" };
            //var maxLengthString =(
            //    from str in someStrings
            //    orderby str.Length descending
            //    select str).First();
            //Console.WriteLine(maxLengthString);

            //Ex10
            //var groupedStudents =
            //    from student in students
            //    join g in groups on student.GroupNumber equals g.GroupNumber
            //    group student by g.DepartmentName into p
            //    select new { Name = p.Key, Students = p};

            //Console.WriteLine("\nStudents by Department: \n");
            //foreach (var item in groupedStudents)
            //{
            //    Console.WriteLine(new string('-',30));
            //    Console.WriteLine("Department: " + item.Name);
            //    Console.WriteLine("Students: ");
            //    foreach (var student in item.Students)
            //    {
            //        Console.WriteLine(student);
            //    }
            //    Console.WriteLine(new string('-', 30));
            //}

            //Ex11
            var groupedWithExt = students.Join(
                groups, st => st.GroupNumber,
                gr => gr.GroupNumber,
                (st, gr) => new { Group = gr.DepartmentName, Student = st})
                .GroupBy(x => x.Group);

            Console.WriteLine("\nStudents by Department Ext: \n");
            foreach (var item in groupedWithExt)
            {
                Console.WriteLine(new string('-', 30));

                Console.Write("Department: ");
                Console.WriteLine(item.Key + "\n");

                Console.WriteLine("Students: \n");
                foreach (var student in item)
                {
                    Console.WriteLine(student.Student + "\n");
                }
             }

        }
    }
}
